package com.ruoyi.integration.service.impl;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.ruoyi.integration.config.InversionServiceProperties;
import com.ruoyi.integration.dto.InversionResultDTO;
import com.ruoyi.integration.dto.UnifiedResponse;
import com.ruoyi.integration.service.InverseService;
import com.ruoyi.integration.vo.DataSourcesVO;
import com.ruoyi.integration.vo.WebMapUrlVO;
import lombok.RequiredArgsConstructor;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.stereotype.Service;
import org.springframework.web.reactive.function.client.WebClient;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.annotation.Resource;
import java.net.URI;
import java.time.Duration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
@RequiredArgsConstructor
public class InverseServiceImpl implements InverseService {

    private final WebClient webClient;

    private final InversionServiceProperties apiClient;

    // 创建ObjectMapper对象：用于将对象转换为JSON字符串，记录日志并查看
    private final ObjectMapper objectMapper;

    // 创建日志记录器
    private final static Logger logger = LoggerFactory.getLogger(InverseServiceImpl.class);

    @Override
    public String pubulishToGeoserver(String bucketName, String fileName) {

        String baseUrl = apiClient.getEndpoint().getBaseUrl(); // http://localhost:8081
        String geoserverReleasePath = apiClient.getApiRouter().getGeoserverRelease(); // /commons/release

        Map<String, Object> requestBody = new HashMap<>();
        requestBody.put("bucket_name", bucketName);
        requestBody.put("file_name", fileName);

        UnifiedResponse<Object> response = webClient.post()
                .uri(uirBuilder -> uirBuilder
                        .scheme("http")
                        .host(URI.create(baseUrl).getHost())
                        .port(URI.create(baseUrl).getPort())
                        .path(geoserverReleasePath)
                        .build())
                .header("Content-Type", "application/json")
                .bodyValue(requestBody)
                .retrieve()
                .bodyToMono(new ParameterizedTypeReference<UnifiedResponse<Object>>() {})
                .block();
        if (response == null || !response.isSuccess()) {
            throw new RuntimeException("Python-Release服务调用失败: " +
                    (response != null ? response.getMessage() : "未知错误"));
        }

        return response.getMessage();
    }

    @Override
    public WebMapUrlVO getWebMapServiceUrl(String bucketName, String fileName) {

        // 1. 分别获取基础URL和接口路径（不提前拼接）
        String baseUrl = apiClient.getEndpoint().getBaseUrl(); // http://localhost:8081
        String geoserverReleasePath = apiClient.getApiRouter().getGeoserverRelease(); // /commons/release

        // 2. 使用uriBuilder正确构建完整URL
        UnifiedResponse<WebMapUrlVO> response = webClient.get()
                .uri(uriBuilder -> uriBuilder
                        .scheme("http") // 从baseUrl解析协议（或直接写死，根据实际情况）
                        .host(URI.create(baseUrl).getHost()) // 从baseUrl解析主机名（localhost）
                        .port(URI.create(baseUrl).getPort()) // 从baseUrl解析端口（8081）
                        .path(geoserverReleasePath) // 添加接口路径（/commons/release）
                        .queryParam("minio_bucket", bucketName)
                        .queryParam("file_name", fileName)
                        .build())
                .header("Content-Type", "application/json")
                .retrieve()
                .bodyToMono(new ParameterizedTypeReference<UnifiedResponse<WebMapUrlVO>>() {})
                .timeout(Duration.ofSeconds(300))
                .block();

        // 2. 检查响应是否成功
        if (response == null || !response.isSuccess()) {
            throw new RuntimeException("Python-get-WebMapService服务调用失败: " +
                    (response != null ? response.getMessage() : "未知错误"));
        }

        // 3. 返回真正的业务数据 (data字段)
        return response.getData();
    }

    @Override
    public String getRcloneMountMinIORefresh(String bucketName) {

        // 1. 分别获取基础URL和接口路径（不提前拼接）
        String baseUrl = apiClient.getEndpoint().getBaseUrl(); // http://localhost:8081
        String RclonePath = apiClient.getApiRouter().getRclone(); // /commons/release

        // 2. 使用uriBuilder正确构建完整URL
        UnifiedResponse<String> response = webClient.get()
                .uri(uriBuilder -> uriBuilder
                        .scheme("http") // 从baseUrl解析协议（或直接写死，根据实际情况）
                        .host(URI.create(baseUrl).getHost()) // 从baseUrl解析主机名（localhost）
                        .port(URI.create(baseUrl).getPort()) // 从baseUrl解析端口（8081）
                        .path(RclonePath) // 添加接口路径（/commons/release）
                        .queryParam("minio_bucket", bucketName)
                        .build())
                .header("Content-Type", "application/json")
                .retrieve()
                .bodyToMono(new ParameterizedTypeReference<UnifiedResponse<String>>() {})
                .timeout(Duration.ofSeconds(300))
                .block();

        if (response != null) {
            return response.getMessage();
        }
        return null;
    }

    @Override
    public InversionResultDTO callEcologicalRetrievalService(String paramId, String dateTime, String mineId, String spatialCoverage, String is, List<DataSourcesVO> dataSources) throws JsonProcessingException {

        String baseUrl = apiClient.getEndpoint().getBaseUrl();
        String inversePath = apiClient.getApiRouter().getInverse();
        // 对于每个生态参量大类构造各自反演的url访问地址
        String prefix = paramId.substring(0, 2); // 0101
        String suffix = paramId.substring(2);

        Map<String, Object> requestBody = new HashMap<>();
        requestBody.put("parameter_code", suffix);
        requestBody.put("collect_time", dateTime);
        requestBody.put("mining_id", mineId);
        requestBody.put("boundary", spatialCoverage);
        requestBody.put("precision", is);
        requestBody.put("data_sources", dataSources);

        //发送请求体之前打印请求体
        logger.info("Sending request to: {}", baseUrl + inversePath + prefix);
        logger.info("Sending request body: {}", objectMapper.writeValueAsString(requestBody));

        // 确保URL格式正确
        String finalUrl =inversePath + prefix;
        logger.info(objectMapper.writeValueAsString(requestBody));
        logger.info(finalUrl);
        UnifiedResponse<InversionResultDTO> response = webClient.post()
                .uri(uriBuilder -> uriBuilder
                        .scheme("http") // 从baseUrl解析协议（或直接写死，根据实际情况）
                        .host(URI.create(baseUrl).getHost()) // 从baseUrl解析主机名（localhost）
                        .port(URI.create(baseUrl).getPort()) // 从baseUrl解析端口（8081）
                        .path(finalUrl)// 添加接口路径（/inverse/01）
                        .build())
                .header("Content-Type", "application/json")
                .bodyValue(requestBody) // 将dataSources（数据源列表）作为HTTP请求体发送至Python后端接口
                .retrieve()
                .bodyToMono(new ParameterizedTypeReference<UnifiedResponse<InversionResultDTO>>() {})
                .block();

        if (response == null || !response.isSuccess()) {
            throw new RuntimeException("Python-Inverse服务调用失败: " +
                    (response != null ? response.getMessage() : "未知错误"));
        }

        return response.getData();
    }
}
